<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Java开发手册v1.7.0（嵩山版） | indasoo</title>
    <meta name="generator" content="VuePress 1.5.0">
    
    <meta name="description" content="indasoo">
    <meta name="theme-color" content="#ffffff">
    <link rel="preload" href="/assets/css/0.styles.3d539848.css" as="style"><link rel="preload" href="/assets/js/app.9351f917.js" as="script"><link rel="preload" href="/assets/js/2.df5978de.js" as="script"><link rel="preload" href="/assets/js/4.3923084e.js" as="script"><link rel="prefetch" href="/assets/js/3.d805f7cc.js"><link rel="prefetch" href="/assets/js/5.1f56bb06.js"><link rel="prefetch" href="/assets/js/6.3f8af928.js"><link rel="prefetch" href="/assets/js/7.f4d6f1dc.js"><link rel="prefetch" href="/assets/js/8.cf518998.js">
    <link rel="stylesheet" href="/assets/css/0.styles.3d539848.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">indasoo</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link">
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="编码规范" class="dropdown-title"><span class="title">编码规范</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/manuals/java/" class="nav-link router-link-active">
  Java
</a></li></ul></div></div> <a href="https://github.com/indasoo/indasoo.github.io" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link">
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="编码规范" class="dropdown-title"><span class="title">编码规范</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/manuals/java/" class="nav-link router-link-active">
  Java
</a></li></ul></div></div> <a href="https://github.com/indasoo/indasoo.github.io" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>java</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html" aria-current="page" class="active sidebar-link">Java开发手册v1.7.0（嵩山版）</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html#发布说明" class="sidebar-link">发布说明</a></li><li class="sidebar-sub-header"><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html#变更记录" class="sidebar-link">变更记录</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html#_1-【一、-编程规约】之【-一-命名风格】章节增加避免种族歧视性词语要求" class="sidebar-link">1. 【一、 编程规约】之【(一) 命名风格】章节增加避免种族歧视性词语要求</a></li><li class="sidebar-sub-header"><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html#_2-【一、-编程规约】之【-四-oop-规约】章节增加bigdecimal等值比较要求" class="sidebar-link">2. 【一、 编程规约】之【(四) OOP 规约】章节增加BigDecimal等值比较要求</a></li><li class="sidebar-sub-header"><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html#_3-【一、-编程规约】之【-六-集合处理】章节修正-hashmap-关于-1024-个元素扩容的次数" class="sidebar-link">3. 【一、 编程规约】之【(六) 集合处理】章节修正 HashMap 关于 1024 个元素扩容的次数</a></li><li class="sidebar-sub-header"><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html#_4-【一、-编程规约】增加【-十-前后端规约】" class="sidebar-link">4. 【一、 编程规约】增加【(十) 前后端规约】</a></li><li class="sidebar-sub-header"><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html#_5-删除【二、异常日志】之【-二-异常处理】章节的-dry原则-要求" class="sidebar-link">5. 删除【二、异常日志】之【(二) 异常处理】章节的“DRY原则”要求</a></li><li class="sidebar-sub-header"><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html#_6-【二、异常日志】之【-三-日志规约】增加日志留存要求" class="sidebar-link">6.【二、异常日志】之【(三) 日志规约】增加日志留存要求</a></li><li class="sidebar-sub-header"><a href="/manuals/java/20200803-java-development-manual-v1.7.0.html#_7-【六、工程结构】之【-一-应用分层】修改架构分层描述" class="sidebar-link">7. 【六、工程结构】之【(一) 应用分层】修改架构分层描述</a></li></ul></li></ul></li><li><a href="/manuals/java/" aria-current="page" class="sidebar-link">Java开发手册</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="java开发手册v1-7-0（嵩山版）"><a href="#java开发手册v1-7-0（嵩山版）" class="header-anchor">#</a> Java开发手册v1.7.0（嵩山版）</h1> <h2 id="发布说明"><a href="#发布说明" class="header-anchor">#</a> 发布说明</h2> <p>2020年8月3日，阿里巴巴技术团队正式发布《Java开发手册》v1.7.0版本，版本代号：嵩山版。首次发布前后端规约。
参考： <a href="https://developer.aliyun.com/ask/310991" target="_blank" rel="noopener noreferrer">嵩山版《Java开发手册》答开发者问<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <h2 id="变更记录"><a href="#变更记录" class="header-anchor">#</a> 变更记录</h2> <p>根据官方文档描述，本次版本改动点如下：</p> <ul><li>1）新增前后端规约 14 条。</li> <li>2）新增禁止任何歧视性用语的约定。</li> <li>3）新增涉及敏感操作的情况下日志需要保存六个月的约定。</li> <li>4）修正 BigDecimal 类中关于 compareTo 和 equals 的等值比较。</li> <li>5）修正 HashMap 关于 1024 个元素扩容的次数。</li> <li>6）修正架构分层规范与相关说明。</li> <li>7）修正泰山版中部分格式错误和描述错误。</li></ul> <p>为便于快速学习，特将本次变更的核心内容提取出来进行记录，以便大家快速学习。</p> <h3 id="_1-【一、-编程规约】之【-一-命名风格】章节增加避免种族歧视性词语要求"><a href="#_1-【一、-编程规约】之【-一-命名风格】章节增加避免种族歧视性词语要求" class="header-anchor">#</a> 1. 【一、 编程规约】之【(一) 命名风格】章节增加避免种族歧视性词语要求</h3> <blockquote><ol start="3"><li>【强制】代码和注释中都要避免使用任何语言的种族歧视性词语。</li></ol> <ul><li>正例：日本人 / 印度人 / blockList / allowList / secondary</li> <li>反例：RIBENGUIZI / Asan / blackList / whiteList / slave</li></ul></blockquote> <h3 id="_2-【一、-编程规约】之【-四-oop-规约】章节增加bigdecimal等值比较要求"><a href="#_2-【一、-编程规约】之【-四-oop-规约】章节增加bigdecimal等值比较要求" class="header-anchor">#</a> 2. 【一、 编程规约】之【(四) OOP 规约】章节增加BigDecimal等值比较要求</h3> <blockquote><p>10.【强制】如上所示 BigDecimal 的等值比较应使用 compareTo()方法，而不是 equals()方法。</p> <p>说明：equals()方法会比较值和精度（1.0 与 1.00 返回结果为 false），而 compareTo()则会忽略精度。</p></blockquote> <h3 id="_3-【一、-编程规约】之【-六-集合处理】章节修正-hashmap-关于-1024-个元素扩容的次数"><a href="#_3-【一、-编程规约】之【-六-集合处理】章节修正-hashmap-关于-1024-个元素扩容的次数" class="header-anchor">#</a> 3. 【一、 编程规约】之【(六) 集合处理】章节修正 HashMap 关于 1024 个元素扩容的次数</h3> <blockquote><ol start="17"><li>【推荐】集合初始化时，指定集合初始值大小。</li></ol> <ul><li>说明：HashMap 使用 HashMap(int initialCapacity) 初始化，如果暂时无法确定集合大小，那么指定默认值（16）即可。</li> <li>正例：initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子（即 loader factor）默认为 0.75，如果暂时无法确定初始值大小，请设置为 16（即默认值）。</li> <li>反例： HashMap 需要放置 1024 个元素，由于没有设置容量初始大小，随着元素增加而被迫不断扩容，resize()方法总共会调用 8 次，反复重建哈希表和数据迁移。当放置的集合元素个数达千万级时会影响程序性能。</li></ul></blockquote> <h3 id="_4-【一、-编程规约】增加【-十-前后端规约】"><a href="#_4-【一、-编程规约】增加【-十-前后端规约】" class="header-anchor">#</a> 4. 【一、 编程规约】增加【(十) 前后端规约】</h3> <p>(十) 前后端规约</p> <blockquote><ol><li>【强制】前后端交互的 API，需要明确协议、域名、路径、请求方法、请求内容、状态码、响应体。</li></ol> <p>说明：</p> <ul><li><p>1） 协议：生产环境必须使用 HTTPS。</p></li> <li><p>2） 路径：每一个 API 需对应一个路径，表示 API 具体的请求地址：</p> <ul><li>a） 代表一种资源，只能为名词，推荐使用复数，不能为动词，请求方法已经表达动作意义。</li> <li>b） URL 路径不能使用大写，单词如果需要分隔，统一使用下划线。</li> <li>c） 路径禁止携带表示请求内容类型的后缀，比如&quot;.json&quot;,&quot;.xml&quot;，通过 accept 头表达即可。</li> <li>3） 请求方法：对具体操作的定义，常见的请求方法如下：</li> <li>a） GET：从服务器取出资源。</li> <li>b） POST：在服务器新建一个资源。</li> <li>c） PUT：在服务器更新资源。</li> <li>d） DELETE：从服务器删除资源。</li></ul></li> <li><p>4） 请求内容：URL 带的参数必须无敏感信息或符合安全要求；body 里带参数时必须设置 Content-Type。</p></li> <li><p>5） 响应体：响应体 body 可放置多种数据类型，由 Content-Type 头来确定。</p></li></ul> <ol start="2"><li>【强制】前后端数据列表相关的接口返回，如果为空，则返回空数组[]或空集合{}。</li></ol> <ul><li>说明：此条约定有利于数据层面上的协作更加高效，减少前端很多琐碎的 null 判断。</li></ul> <ol start="3"><li>【强制】服务端发生错误时，返回给前端的响应信息必须包含 HTTP 状态码，errorCode、errorMessage、用户提示信息四个部分。</li></ol> <ul><li>说明：四个部分的涉众对象分别是浏览器、前端开发、错误排查人员、用户。其中输出给用户的提示信息要求：简短清晰、提示友好，引导用户进行下一步操作或解释错误原因，提示信息可以包括错误原因、上下文环境、推荐操作等。 errorCode：参考附表 3。errorMessage：简要描述后端出错原因，便于错误排查人员快速定位问题，注意不要包含敏感数据信息。</li> <li>正例：常见的 HTTP 状态码如下
<ul><li>1） 200 OK: 表明该请求被成功地完成，所请求的资源发送到客户端。</li> <li>2） 401 Unauthorized: 请求要求身份验证，常见对于需要登录而用户未登录的情况。</li> <li>3） 403 Forbidden：服务器拒绝请求，常见于机密信息或复制其它登录用户链接访问服务器的情况。</li> <li>4） 404 Not Found: 服务器无法取得所请求的网页，请求资源不存在。</li> <li>5） 500 Internal Server Error: 服务器内部错误。</li></ul></li></ul> <ol start="4"><li>【强制】在前后端交互的 JSON 格式数据中，所有的 key 必须为小写字母开始的lowerCamelCase 风格，符合英文表达习惯，且表意完整。</li></ol> <ul><li>正例：errorCode / errorMessage / assetStatus / menuList / orderList / configFlag</li> <li>反例：ERRORCODE / ERROR_CODE / error_message / error-message / errormessage / ErrorMessage / msg</li></ul> <ol start="5"><li><p>【强制】errorMessage 是前后端错误追踪机制的体现，可以在前端输出到 type=&quot;hidden&quot;文字类控件中，或者用户端的日志中，帮助我们快速地定位出问题。</p></li> <li><p>【强制】对于需要使用超大整数的场景，服务端一律使用 String 字符串类型返回，禁止使用Long 类型。</p></li></ol> <ul><li>说明：Java 服务端如果直接返回 Long 整型数据给前端，JS 会自动转换为 Number 类型（注：此类型为双精度浮点数，表示原理与取值范围等同于 Java 中的 Double）。Long 类型能表示的最大值是 2 的 63 次方-1，在取值范围之内，超过 2 的 53 次方 (9007199254740992)的数值转化为 JS 的 Number 时，有些数值会有精度损失。扩展说明，在 Long 取值范围内，任何 2 的指数次整数都是绝对不会存在精度损失的，所以说精度损失是一个概率问题。若浮点数尾数位与指数位空间不限，则可以精确表示任何整数，但很不幸，双精度浮点数的尾数位只有 52 位。</li> <li>反例：通常在订单号或交易号大于等于 16 位，大概率会出现前后端单据不一致的情况，比如，&quot;orderId&quot;: 362909601374617692，前端拿到的值却是: 362909601374617660。</li></ul> <ol start="7"><li>【强制】HTTP 请求通过 URL 传递参数时，不能超过 2048 字节。</li></ol> <ul><li><p>说明：不同浏览器对于 URL 的最大长度限制略有不同，并且对超出最大长度的处理逻辑也有差异，2048字节是取所有浏览器的最小值。</p></li> <li><p>反例：某业务将退货的商品 id 列表放在 URL 中作为参数传递，当一次退货商品数量过多时，URL 参数超长，传递到后端的参数被截断，导致部分商品未能正确退货。</p></li></ul> <ol start="8"><li>【强制】HTTP 请求通过 body 传递内容时，必须控制长度，超出最大长度后，后端解析会出错。</li></ol> <ul><li>说明：nginx 默认限制是 1MB，tomcat 默认限制为 2MB，当确实有业务需要传较大内容时，可以通过调大服务器端的限制。</li></ul> <ol start="9"><li><p>【强制】在翻页场景中，用户输入参数的小于 1，则前端返回第一页参数给后端；后端发现用户输入的参数大于总页数，直接返回最后一页。</p></li> <li><p>【强制】服务器内部重定向必须使用 forward；外部重定向地址必须使用 URL 统一代理模块生成，否则会因线上采用 HTTPS 协议而导致浏览器提示“不安全”，并且还会带来 URL 维护不一致的问题。</p></li> <li><p>【推荐】服务器返回信息必须被标记是否可以缓存，如果缓存，客户端可能会重用之前的请求结果。</p></li></ol> <ul><li>说明：缓存有利于减少交互次数，减少交互的平均延迟。</li> <li>正例：http 1.1 中，s-maxage 告诉服务器进行缓存，时间单位为秒，用法如下，
response.setHeader(&quot;Cache-Control&quot;, &quot;s-maxage=&quot; + cacheSeconds);</li></ul> <ol start="12"><li>【推荐】服务端返回的数据，使用 JSON 格式而非 XML。</li></ol> <ul><li>说明：尽管 HTTP 支持使用不同的输出格式，例如纯文本，JSON，CSV，XML，RSS 甚至 HTML。如果我们使用的面向用户的服务，应该选择 JSON 作为通信中使用的标准数据交换格式，包括请求和响应。此外，application/JSON 是一种通用的 MIME 类型，具有实用、精简、易读的特点。</li></ul> <ol start="13"><li>【推荐】前后端的时间格式统一为&quot;yyyy-MM-dd HH:mm:ss&quot;，统一为 GMT。</li></ol> <p>14.【参考】在接口路径中不要加入版本号，版本控制在 HTTP 头信息中体现，有利于向前兼容。</p> <ul><li>说明：当用户在低版本与高版本之间反复切换工作时，会导致迁移复杂度升高，存在数据错乱风险。</li></ul></blockquote> <h3 id="_5-删除【二、异常日志】之【-二-异常处理】章节的-dry原则-要求"><a href="#_5-删除【二、异常日志】之【-二-异常处理】章节的-dry原则-要求" class="header-anchor">#</a> 5. 删除【二、异常日志】之【(二) 异常处理】章节的“DRY原则”要求</h3> <blockquote><p><s>14. 【参考】避免出现重复的代码（Don't Repeat Yourself），即 DRY 原则。</s></p> <ul><li><s>说明：随意复制和粘贴代码，必然会导致代码的重复，在以后需要修改时，需要修改所有的副本，容易遗漏。必要时抽取共性方法，或者抽象公共类，甚至是组件化。</s></li> <li><s>正例：一个类中有多个 public 方法，都需要进行数行相同的参数校验操作，这个时候请抽取：</s> <s>private boolean checkParam(DTO dto) {...}</s></li></ul></blockquote> <h3 id="_6-【二、异常日志】之【-三-日志规约】增加日志留存要求"><a href="#_6-【二、异常日志】之【-三-日志规约】增加日志留存要求" class="header-anchor">#</a> 6.【二、异常日志】之【(三) 日志规约】增加日志留存要求</h3> <blockquote><ol start="3"><li>【强制】根据国家法律，网络运行状态、网络安全事件、个人敏感信息操作等相关记录，留存的日志不少于六个月，并且进行网络多机备份。</li></ol></blockquote> <h3 id="_7-【六、工程结构】之【-一-应用分层】修改架构分层描述"><a href="#_7-【六、工程结构】之【-一-应用分层】修改架构分层描述" class="header-anchor">#</a> 7. 【六、工程结构】之【(一) 应用分层】修改架构分层描述</h3> <blockquote><ol><li>【推荐】根据业务架构实践，结合业界分层规范与流行技术框架分析，推荐分层结构如图所示，默认上层依赖于下层，箭头关系表示可直接依赖，如：开放 API 层可以依赖于 Web 层（Controller 层），也可以直接依赖于 Service 层，依此类推：</li></ol> <ul><li><p><img src="/assets/img/application-layer.8012cf36.png" alt=""></p></li> <li><p>开放 API 层：可直接封装 Service 接口暴露成 RPC 接口；通过 Web 封装成 http 接口；网关控制层等。</p></li> <li><p>终端显示层：各个端的模板渲染并执行显示的层。当前主要是 velocity 渲染，JS 渲染，JSP 渲染，移动端展示等。</p></li> <li><p>Web 层：主要是对访问控制进行转发，各类基本参数校验，或者不复用的业务简单处理等。</p></li> <li><p>Service 层：相对具体的业务逻辑服务层。</p></li> <li><p>Manager 层：通用业务处理层，它有如下特征：</p> <ul><li>1） 对第三方平台封装的层，预处理返回结果及转化异常信息，适配上层接口。</li> <li>2） 对 Service 层通用能力的下沉，如缓存方案、中间件通用处理。</li> <li>3） 与 DAO 层交互，对多个 DAO 的组合复用。</li></ul></li> <li><p>DAO 层：数据访问层，与底层 MySQL、Oracle、Hbase、OB 等进行数据交互。</p></li> <li><p>第三方服务：包括其它部门 RPC 服务接口，基础平台，其它公司的 HTTP 接口，如淘宝开放平台、支付宝付款服务、高德地图服务等。</p></li> <li><p>外部数据接口：外部（应用）数据存储服务提供的接口，多见于数据迁移场景中。</p></li></ul></blockquote></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/indasoo/indasoo.github.io/edit/develop/docs/manuals/java/20200803-java-development-manual-v1.7.0.md" target="_blank" rel="noopener noreferrer">Edit this page on GitHub</a> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></div> <!----></footer> <div class="page-nav"><p class="inner"><!----> <span class="next"><a href="/manuals/java/" class="router-link-active">
        Java开发手册
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"></div></div>
    <script src="/assets/js/app.9351f917.js" defer></script><script src="/assets/js/2.df5978de.js" defer></script><script src="/assets/js/4.3923084e.js" defer></script>
  </body>
</html>
